package com.dhcc.bpm.modules.orga.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.dhcc.bpm.common.sm.SM2Utils;
import com.dhcc.bpm.common.utils.EmailUtils;
import com.dhcc.bpm.common.utils.RSAKeyPairGenUtil;
import com.dhcc.bpm.common.utils.UUIDGenerator;
import com.dhcc.bpm.modules.common.vo.SelectVo;
import com.dhcc.bpm.modules.log.vo.AppApiViewVo;
import com.dhcc.bpm.modules.log.vo.AppRankVo;
import com.dhcc.bpm.modules.orga.entity.App;
import com.dhcc.bpm.modules.orga.entity.AppApi;
import com.dhcc.bpm.modules.orga.entity.Orga;
import com.dhcc.bpm.modules.orga.entity.TestApply;
import com.dhcc.bpm.modules.orga.mapper.AppMapper;
import com.dhcc.bpm.modules.orga.service.IAppService;
import com.dhcc.bpm.modules.orga.service.IOrgaService;
import com.dhcc.bpm.modules.orga.service.IProduceApplyService;
import com.dhcc.bpm.modules.orga.service.ITestApplyService;
import com.dhcc.bpm.modules.orga.vo.AppTestNewVo;
import com.dhcc.bpm.modules.orga.vo.AppTestVo;
import com.dhcc.bpm.modules.orga.vo.AppVO;
import com.dhcc.bpm.modules.orga.vo.ProduceApplyVO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springblade.core.mp.base.BaseServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;

/**
 * @ClassName AppServiceImpl
 * @Description 应用/渠道信息 服务实现类
 * @Author daina
 * @Date 2020/2/24 19:25
 * @Version V1.0
 * @Copyright: 2020 东华软件 . All rights reserved.
 */
@Service("opc_app")
public class AppServiceImpl extends BaseServiceImpl<AppMapper, App> implements IAppService {
    private static final Logger log = LoggerFactory.getLogger(AppServiceImpl.class);
    @Autowired
    private AppMapper appMapper;
    @Autowired
    private EmailUtils emailUtils;
    @Autowired
    private IOrgaService orgaService;
    @Autowired
    private IProduceApplyService produceApplyService;

    @Autowired
    private ITestApplyService testApplyService;

    @Value("${bpm.message.title}")
    private String mailTitle;
    @Value("${app.size}")
    private String size;
    @Value("${app.algorithm}")
    private String algorithm;
    @Value("${app.isFlag}")
    private Boolean isFlag;
    @Value("${bpm.approval.isSendMail}")
    private boolean isSendFlag;

    @Override
    public IPage<AppVO> selectAppPage(IPage<AppVO> page, AppVO app) {
        return page.setRecords(baseMapper.selectAppPage(page, app));
    }

    @Override
    public IPage<AppVO> listApp(IPage<AppVO> page, AppVO app) {
        List<AppVO> voLists = baseMapper.listApp(page, app);
        for (AppVO vo : voLists) {

            if ("2".equals(app.getEnv().toString())) {
                // 测试服务器IP地址
                if (null != vo.getId()) {
                    TestApply testApply = testApplyService.selectByAppId(vo.getId());
                    if (testApply != null) {
                        vo.setTestApplyId(testApply.getId().toString());
                        if (!"".equals(testApply.getIp()) && null != testApply.getIp()) {
                            vo.setIp(testApply.getIp());
                        }
                    }
                }
            } else if ("1".equals(app.getEnv().toString())) {
                // 生产服务器IP地址
                List<ProduceApplyVO> produceApplyLists = produceApplyService.selectProApplyByAppId(vo.getId());
                if(produceApplyLists.size()>0){
                    ProduceApplyVO produceApply = produceApplyLists.get(0);
                    if (produceApply != null) {
                        vo.setProduceApplyId(produceApply.getId().toString());
                        if (!"".equals(produceApply.getIp()) && null != produceApply.getIp()) {
                            vo.setIp(produceApply.getIp());
                        }
                    }
                }

            }
        }

        return page.setRecords(voLists);
    }

    @Override
    public IPage<AppVO> selectAppFlow(IPage<AppVO> page, AppVO app) {
        return page.setRecords(baseMapper.selectAppFlow(page, app));
    }

    @Override
    public IPage<AppVO> selectControllerAppListPage(IPage<AppVO> page, AppVO app) {
        return page.setRecords(baseMapper.selectControllerAppList(page, app));
    }

    @Override
    public App selectByAppCode(String appId) {
        return appMapper.selectByAppCode(appId);
    }

    @Override
    public IPage<AppVO> selectUnControllerAppList(IPage<AppVO> page, AppVO app) {
        return page.setRecords(baseMapper.selectUnControllerAppList(page, app));
    }

    @Override
    public IPage<AppVO> UnControllerOrgaGateList(IPage<AppVO> page, AppVO app) {
        return page.setRecords(baseMapper.UnControllerOrgaGateList(page, app));
    }

    @Override
    public int updateOpc_app_api(Long opc_app_id, String valid_status) {
        return baseMapper.updateOpc_app_api(opc_app_id, valid_status);
    }

    @Override
    public int updateSingleOpc_app_api(AppApi appApi) {
        return baseMapper.updateSingleOpc_app_api(appApi);
    }

    @Override
    public List<AppApi> listRelatedApi(Long opcAppId) {
        return baseMapper.listRelatedApi(opcAppId);
    }

    @Override
    public App selectAppByAppCode(String appCode) {
        return baseMapper.selectByAppCode(appCode);
    }

    @Override
    public int updateRefreshStatus(App app) {
        return baseMapper.updateRefreshStatus(app);
    }

    @Override
    public List<App> listByProductId(Long opcProductId) {
        return baseMapper.listByProductId(opcProductId);
    }

    @Override
    public boolean approvalCreateAppInfo(App app) {
        try {
            Map<String, Object> keyMap = null;
            Map<String, Object> keyEncrypMap = null;
            String publicKey = null;
            String privateKey = null;
            String publicEncrypKey = null;
            String privateEncrypKey = null;
            String appSecret = UUIDGenerator.getUUID();
            if (app.getEnv() == 0) {
                app.setAppSecret(appSecret);
                mailTitle += "生产环境";
            } else {
                app.setTestAppSecret(appSecret);
                mailTitle += "测试环境";
            }
            if (!isFlag) {
                app.setRefreshStatus("0");
                updateById(app);
                return true;
            }

            //门户增加签名加密算法类型(1:RSA,2:SM2)
            if(null != app.getEncrypType() && !"".equals(app.getEncrypType())){
                algorithm = app.getEncrypType() == 1L ? "RSA" : "SM2";
            }

            //algorithm签名秘钥算法类型：SM2, RSA,默认RSA
            if (!"RSA".equals(algorithm)) {
                keyMap = SM2Utils.generateKeyPair();
                privateKey = keyMap.get(SM2Utils.PRIVATE_KEY).toString();
                publicKey = keyMap.get(SM2Utils.PUBLIC_KEY).toString();
            } else {
                keyMap = RSAKeyPairGenUtil.initKey(size, algorithm);
                privateKey = RSAKeyPairGenUtil.getPrivateKey(keyMap);
                publicKey = RSAKeyPairGenUtil.getPublicKey(keyMap);
            }
            //algorithmEncryp：加解密算法类型：SM2, RSA,默认SM2
            if ("SM2".equals(algorithm)) {
                keyEncrypMap = SM2Utils.generateKeyPair();
                privateEncrypKey = keyEncrypMap.get(SM2Utils.PRIVATE_KEY).toString();
                publicEncrypKey = keyEncrypMap.get(SM2Utils.PUBLIC_KEY).toString();
                app.setEncrypType(2L);  //加密类型  0：SM2
            } else {
                keyEncrypMap = RSAKeyPairGenUtil.initKey(size, algorithm);
                privateEncrypKey = RSAKeyPairGenUtil.getPrivateKey(keyEncrypMap);
                publicEncrypKey = RSAKeyPairGenUtil.getPublicKey(keyEncrypMap);
                app.setEncrypType(1L); //加密类型  1：RSA
            }

            if (app.getEnv() == 0) {
                app.setPublicKey(publicKey);
                app.setPrivateKey(privateKey);
                app.setPublicEncryptKey(publicEncrypKey);
                app.setPrivateEncryptKey(privateEncrypKey);
                app.setAppSecret(appSecret);
                mailTitle += "生产环境私钥";
            } else {
                app.setTestPublicKey(publicKey);
                app.setTestPrivateKey(privateKey);
                app.setTestPublicEncryptKey(publicEncrypKey);
                app.setTestPrivateEncryptKey(privateEncrypKey);
                app.setTestAppSecret(appSecret);
                mailTitle += "测试环境私钥";
            }
            app.setRefreshStatus("0");
            updateById(app);
            if (isSendFlag) {
                Orga orga = orgaService.getById(app.getOpcOrgaId());
                if (orga != null && orga.getOrgaEmail() != null) {
                    emailUtils.sendEmail(mailTitle, orga.getOrgaEmail(), mailTitle, privateKey);
                }
            }
        } catch (Exception e) {
            log.error("生成应用/渠道秘钥信息异常:{}", e);
            return false;
        } finally {

        }
        return true;
    }

    @Override
    public boolean approvalCreateAppInfoProcess(App app) {
        try {
            Map<String, Object> keyMap = null;
            Map<String, Object> keyEncrypMap = null;
            String publicKey = null;
            String privateKey = null;
            String publicEncrypKey = null;
            String privateEncrypKey = null;
            String testPublicKey = null;
            String testPrivateKey = null;
            String testPublicEncrypKey = null;
            String testPrivateEncrypKey = null;
            app.setAppSecret(UUIDGenerator.getUUID());
            app.setTestAppSecret(UUIDGenerator.getUUID());
            if (!isFlag) {
                app.setRefreshStatus("0");
                updateById(app);
                return true;
            }

            //门户增加签名加密算法类型(1:RSA,2:SM2)
            if(null != app.getEncrypType() && !"".equals(app.getEncrypType())){
                algorithm = app.getEncrypType() == 1L ? "RSA" : "SM2";
            }

            //algorithm签名秘钥算法类型：SM2, RSA,默认RSA
            if (!"RSA".equals(algorithm)) {
                keyMap = SM2Utils.generateKeyPair();
                privateKey = keyMap.get(SM2Utils.PRIVATE_KEY).toString();
                publicKey = keyMap.get(SM2Utils.PUBLIC_KEY).toString();
                keyMap = SM2Utils.generateKeyPair();
                testPrivateKey = keyMap.get(SM2Utils.PRIVATE_KEY).toString();
                testPublicKey = keyMap.get(SM2Utils.PUBLIC_KEY).toString();
            } else {
                keyMap = RSAKeyPairGenUtil.initKey(size, algorithm);
                privateKey = RSAKeyPairGenUtil.getPrivateKey(keyMap);
                publicKey = RSAKeyPairGenUtil.getPublicKey(keyMap);
                keyMap = RSAKeyPairGenUtil.initKey(size, algorithm);
                testPrivateKey = RSAKeyPairGenUtil.getPrivateKey(keyMap);
                testPublicKey = RSAKeyPairGenUtil.getPublicKey(keyMap);
            }
            //algorithmEncryp：加解密算法类型：SM2, RSA,默认SM2
            if ("SM2".equals(algorithm)) {
                keyEncrypMap = SM2Utils.generateKeyPair();
                privateEncrypKey = keyEncrypMap.get(SM2Utils.PRIVATE_KEY).toString();
                publicEncrypKey = keyEncrypMap.get(SM2Utils.PUBLIC_KEY).toString();
                keyEncrypMap = SM2Utils.generateKeyPair();
                testPrivateEncrypKey = keyEncrypMap.get(SM2Utils.PRIVATE_KEY).toString();
                testPublicEncrypKey = keyEncrypMap.get(SM2Utils.PUBLIC_KEY).toString();
                app.setEncrypType(2L);  //加密类型  0：SM2
            } else {
                keyEncrypMap = RSAKeyPairGenUtil.initKey(size, algorithm);
                privateEncrypKey = RSAKeyPairGenUtil.getPrivateKey(keyEncrypMap);
                publicEncrypKey = RSAKeyPairGenUtil.getPublicKey(keyEncrypMap);
                keyEncrypMap = RSAKeyPairGenUtil.initKey(size, algorithm);
                testPrivateEncrypKey = RSAKeyPairGenUtil.getPrivateKey(keyEncrypMap);
                testPublicEncrypKey = RSAKeyPairGenUtil.getPublicKey(keyEncrypMap);
                app.setEncrypType(1L); //加密类型  1：RSA
            }

            app.setPublicKey(publicKey);
            app.setPrivateKey(privateKey);
            app.setPublicEncryptKey(publicEncrypKey);
            app.setPrivateEncryptKey(privateEncrypKey);
            app.setTestPublicKey(testPublicKey);
            app.setTestPrivateKey(testPrivateKey);
            app.setTestPublicEncryptKey(testPublicEncrypKey);
            app.setTestPrivateEncryptKey(testPrivateEncrypKey);
            mailTitle += "测试环境私钥";
            app.setRefreshStatus("0");
            updateById(app);
            if (isSendFlag) {
                Orga orga = orgaService.getById(app.getOpcOrgaId());
                if (orga != null && orga.getOrgaEmail() != null) {
                    emailUtils.sendEmail(mailTitle, orga.getOrgaEmail(), mailTitle, testPrivateKey);
                }
            }
        } catch (Exception e) {
            log.error("生成应用/渠道秘钥信息异常:{}", e);
            return false;
        } finally {

        }
        return true;
    }

    @Override
    public IPage<AppApiViewVo> selectAppList(IPage<AppApiViewVo> page, AppApiViewVo appApiViewVo) {
        return appMapper.selectAppList(page, appApiViewVo);
    }

    @Override
    public int countApp() {
        return appMapper.countApp();
    }

    /**
     * @param page
     * @param app
     * @return com.baomidou.mybatisplus.core.metadata.IPage<com.dhcc.bpm.modules.orga.vo.AppVO>
     * @Description 应用变更信息
     * @Author sjm
     * @Date 14:10 2020/2/25 0025
     **/
    @Override
    public IPage<AppVO> changeList(IPage<AppVO> page, AppVO app) {
        return page.setRecords(baseMapper.changeList(page, app));
    }

    /**
     * @param id
     * @return com.dhcc.bpm.modules.orga.vo.AppTestVo
     * @Description 申请测试信息
     * @Author sjm
     * @Date 18:47 2020/2/26 0026
     **/
    @Override
    public AppTestVo selectAppInfo(Long id) {
        return appMapper.selectAppInfo(id);
    }

    /**
     * @param id
     * @return com.dhcc.bpm.modules.orga.vo.AppTestNewVo
     * @Description 查询变更后申请测试信息
     * @Author sjm
     * @Date 9:31 2020/2/27 0027
     **/
    @Override
    public AppTestNewVo selectAppInfoNew(Long id) {
        return appMapper.selectAppInfoNew(id);
    }

    @Override
    public int changeNum(Long parentId) {
        return appMapper.changeNum(parentId);
    }

    /**
     * @param appId
     * @return java.util.List<com.dhcc.bpm.modules.orga.vo.AppVO>
     * @throws
     * @Description 渠道号查询
     * @Author xiafayu
     * @Date 2020/4/23 18:10
     **/
    @Override
    public List<AppVO> findByAppId(String appId) {
        return appMapper.findByAppId(appId);
    }

    @Override
    public List<AppVO> findByAppIds(AppVO appVO) {
        return appMapper.findByAppIds(appVO);
    }

    @Override
    public List<AppVO> getAppList(AppVO appVO) {
        return appMapper.getAppList(appVO);
    }

    @Override
    public List<AppVO> getAppListByBasePro(AppVO appVO) {
        return appMapper.getAppListByBasePro(appVO);
    }

    @Override
    public List<AppVO> getAppListBySysId(AppVO appVO) {
        return appMapper.getAppListBySysId(appVO);
    }

    @Override
    public List<SelectVo> selectByAppName() {
        return appMapper.selectByAppName();
    }

    @Override
    public boolean delAppIdAndPid(List<Long> ids) {
        return appMapper.delAppIdAndPid(ids);
    }

    @Override
    public List<App> findByPId(String pid) {
        return appMapper.findByPId(pid);
    }

    @Override
    public List<App> getListByExpire(String expire) {
        return appMapper.getListByExpire(expire);
    }

    @Override
    public List<SelectVo> selectAppName() {
        return appMapper.selectAppName();
    }

    @Override
    public IPage<AppRankVo> countAppNum(IPage<AppRankVo> page, AppRankVo appRank) {
        return appMapper.countAppNum(page, appRank);
    }
}
